import AMapLoader from '@amap/amap-jsapi-loader';

/* ### 高德地图工具函数（amapUtils.js）
这个文件封装了与高德地图API交互的各种工具函数，是地图功能的基础。 */

// 高德地图配置
const MAP_CONFIG = {
  key: '9112a611732d1f019034ac76e2e10e4f',
  version: '2.0',
  plugins: [
    'AMap.Scale',
    'AMap.ToolBar',
    'AMap.ElasticMarker',
    'AMap.MoveAnimation',
    'AMap.Driving'
  ]
};

// 地图实例
let mapInstance = null;

/**
 * 初始化高德地图
 * @param {string} containerId - 地图容器ID
 * @returns {Promise<AMap.Map>} - 地图实例
 */
export const initAMap = async (containerId) => {
  try {
    if (!mapInstance) {
      window._AMapSecurityConfig = {
        securityJsCode: 'a0fdad72fcc6f391bca6686363f76d16', // 需要替换为实际的安全密钥
      };
      
      const AMap = await AMapLoader.load(MAP_CONFIG);
      
      // 使用更详细的配置初始化地图，确保显示地名等信息
      mapInstance = new AMap.Map(containerId, {
        viewMode: '2D',
        zoom: 11,        // 较小的缩放值，显示更多地图区域
        center: [116.397428, 39.90923],
        resizeEnable: true,
        mapStyle: 'amap://styles/normal', // 标准地图样式
        features: ['bg', 'road', 'building', 'point'], // 显示背景、道路、建筑和兴趣点
        showLabel: true, // 显示文字标签
        showIndoorMap: false, // 不显示室内地图以减少干扰
        defaultLayer: 1 // 确保使用标准图层
      });
      
      // 添加比例尺控件
      try {
        mapInstance.addControl(new AMap.Scale());
      } catch (error) {
        console.warn('无法添加比例尺控件:', error);
      }
      
      // 添加工具条控件
      try {
        mapInstance.addControl(new AMap.ToolBar({
          position: 'RB'
        }));
      } catch (error) {
        console.warn('无法添加工具条控件:', error);
      }
      
      // 强制显示默认图层 - 这很重要
      try {
        // 确保默认图层可见
        const defaultLayer = new AMap.TileLayer();
        defaultLayer.setMap(mapInstance);
      } catch (error) {
        console.warn('添加默认图层失败:', error);
      }
    }
    return mapInstance;
  } catch (e) {
    console.error('地图初始化失败:', e);
    throw e;
  }
};

/**
 * 创建物流路线 - 使用基础组件替代PathNavigator
 * @param {Array} path - 路径坐标点数组 [[lng1, lat1], [lng2, lat2], ...]
 * @param {Object} options - 路线配置选项
 * @returns {Object} - 包含路线和标记的对象
 */
export const createLogisticsRoute = async (map, path, options = {}) => {
  try {
    const AMap = await AMapLoader.load(MAP_CONFIG);
    
    // 设置默认选项
    const defaultOptions = {
      pathLineStyle: {
        strokeColor: '#1890ff',    // 蓝色线条
        strokeWeight: 8,           // 更粗的线条，更明显
        strokeOpacity: 0.9,        // 更高的不透明度
        strokeStyle: 'solid',
        lineJoin: 'round',
        strokeDasharray: [10, 5],  // 虚线效果
        showDir: true,             // 显示方向箭头
        dirColor: '#1890ff',       // 方向箭头颜色
        zIndex: 50                 // 确保线条在图层上方
      },
      markerStyle: {
        content: '配',
        offset: new AMap.Pixel(-13, -30)
      }
    };
    
    // 合并选项
    const mergedOptions = { ...defaultOptions, ...options };
    
    // 创建路径线条
    const polyline = new AMap.Polyline({
      path: path,
      ...mergedOptions.pathLineStyle,
      map: map
    });
    
    // 创建起点和终点标记，使用更明显的样式
    const startMarker = new AMap.Marker({
      map,
      position: path[0],
      content: '<div class="logistics-marker logistics-start">始</div>',
      offset: new AMap.Pixel(-15, -30),
      zIndex: 120
    });
    
    const endMarker = new AMap.Marker({
      map,
      position: path[path.length - 1],
      content: '<div class="logistics-marker logistics-end">终</div>',
      offset: new AMap.Pixel(-15, -30),
      zIndex: 110
    });
    
    // 创建移动标记
    const marker = new AMap.Marker({
      map,
      position: path[0],
      content: `<div class="logistics-marker logistics-vehicle">${mergedOptions.markerStyle.content}</div>`,
      offset: new AMap.Pixel(-15, -30),
      zIndex: 130
    });
    
    // 添加InfoWindow显示地点信息
    try {
      const startInfoWindow = new AMap.InfoWindow({
        content: '<div style="padding:5px;">起点: 发货地</div>',
        offset: new AMap.Pixel(0, -35)
      });
      
      const endInfoWindow = new AMap.InfoWindow({
        content: '<div style="padding:5px;">终点: 收货地</div>',
        offset: new AMap.Pixel(0, -35)
      });
      
      startMarker.on('mouseover', function() {
        startInfoWindow.open(map, startMarker.getPosition());
      });
      
      endMarker.on('mouseover', function() {
        endInfoWindow.open(map, endMarker.getPosition());
      });
    } catch (e) {
      console.warn('创建信息窗体失败:', e);
    }
    
    // 模拟路径动画的变量
    let currentIndex = 0;
    let animationTimer = null;
    let isPlaying = false;
    const moveCallbacks = [];
    const endCallbacks = [];
    
    // 移动到路径上的某个点
    const moveToPoint = (index) => {
      if (index >= 0 && index < path.length) {
        marker.setPosition(path[index]);
        currentIndex = index;
        
        // 触发移动回调
        moveCallbacks.forEach(callback => {
          try {
            callback({
              target: {
                getPosition: () => path[currentIndex]
              }
            });
          } catch (e) {
            console.warn('移动回调执行错误:', e);
          }
        });
      }
    };
    
    // 开始动画
    const startAnimation = () => {
      if (isPlaying) return;
      
      isPlaying = true;
      const animate = () => {
        if (!isPlaying) return;
        
        currentIndex++;
        if (currentIndex >= path.length) {
          currentIndex = path.length - 1;
          isPlaying = false;
          
          // 触发结束回调
          endCallbacks.forEach(callback => {
            try {
              callback();
            } catch (e) {
              console.warn('结束回调执行错误:', e);
            }
          });
          return;
        }
        
        moveToPoint(currentIndex);
        animationTimer = setTimeout(animate, 100); // 每100毫秒移动一次
      };
      
      animate();
    };
    
    // 停止动画
    const stopAnimation = () => {
      isPlaying = false;
      if (animationTimer) {
        clearTimeout(animationTimer);
        animationTimer = null;
      }
    };
    
    // 移动到结束位置
    const moveToLast = () => {
      moveToPoint(path.length - 1);
    };
    
    // 模拟事件监听
    const on = (eventName, callback) => {
      if (eventName === 'move') {
        moveCallbacks.push(callback);
      } else if (eventName === 'end') {
        endCallbacks.push(callback);
      }
    };
    
    return {
      polyline,
      marker,
      startMarker,
      endMarker,
      // 开始移动
      start: startAnimation,
      // 暂停移动
      pause: stopAnimation,
      // 恢复移动
      resume: startAnimation,
      // 停止移动
      stop: stopAnimation,
      // 模拟PathNavigator的接口
      pathNavigator: {
        on,
        moveToLast
      }
    };
  } catch (e) {
    console.error('创建物流路线失败:', e);
    throw e;
  }
};

/**
 * 规划并显示物流路线
 * @param {AMap.Map} map - 地图实例
 * @param {Array} startPosition - 起点坐标 [lng, lat]
 * @param {Array} endPosition - 终点坐标 [lng, lat]
 * @param {Function} callback - 规划完成回调
 */
export const planLogisticsRoute = async (map, startPosition, endPosition, callback) => {
  try {
    const AMap = await AMapLoader.load(MAP_CONFIG);
    
    // 尝试添加路网图层，但不使用getLayer检查，避免兼容性问题
    try {
      // 直接使用plugin方法添加图层，不进行前置检查
      map.plugin(['AMap.TileLayer'], function() {
        try {
          const roadNetLayer = new AMap.TileLayer.RoadNet();
          map.add(roadNetLayer);
        } catch (e) {
          console.warn('添加路网图层失败，但不影响主要功能:', e);
        }
      });
    } catch (e) {
      console.warn('添加地图图层失败，继续执行其他操作:', e);
    }
    
    // 创建驾车实例
    const driving = new AMap.Driving({
      map,
      policy: AMap.DrivingPolicy.LEAST_TIME,
      autoFitView: true,           // 自动调整地图视野
      showTraffic: true,           // 显示路况信息
      hideMarkers: true,           // 隐藏默认的起终点图标，我们将使用自定义图标
      extensions: 'all'            // 返回详细信息
    });
    
    // 开始搜索
    driving.search(
      startPosition,
      endPosition,
      { waypoints: [] },
      function(status, result) {
        if (status === 'complete') {
          // 清除驾车规划插件默认的路线显示
          driving.clear();
          
          // 获取规划路径坐标点
          const path = [];
          if (result.routes && result.routes.length) {
            const route = result.routes[0];
            route.steps.forEach(step => {
              path.push(...step.path);
            });
          }
          
          // 设置地图视野，确保起点和终点都在视野内
          try {
            const bounds = new AMap.Bounds(
              [Math.min(startPosition[0], endPosition[0]), Math.min(startPosition[1], endPosition[1])],
              [Math.max(startPosition[0], endPosition[0]), Math.max(startPosition[1], endPosition[1])]
            );
            map.setBounds(bounds, true, [50, 50, 50, 50]);
            
            // 放大地图以显示更多细节
            setTimeout(() => {
              // 调整缩放级别确保能看到足够的地图细节
              const currentZoom = map.getZoom();
              if (currentZoom > 13) { // 如果缩放太大，减小缩放级别
                map.setZoom(13);
              } else if (currentZoom < 10) { // 如果缩放太小，增加缩放级别
                map.setZoom(10);
              }
            }, 500);
          } catch (e) {
            console.warn('设置地图视野失败:', e);
          }
          
          if (callback && typeof callback === 'function') {
            callback({
              status: 'success',
              path,
              result
            });
          }
        } else {
          if (callback && typeof callback === 'function') {
            callback({
              status: 'error',
              result
            });
          }
        }
      }
    );
  } catch (e) {
    console.error('路线规划失败:', e);
    throw e;
  }
};

/**
 * 地理编码服务 - 地址转坐标
 * @param {string} address - 地址
 * @returns {Promise<Array>} - 坐标 [lng, lat]
 */
export const geocodeAddress = async (address) => {
  if (!address) {
    throw new Error('地址不能为空');
  }
  
  try {
    const AMap = await AMapLoader.load({
      ...MAP_CONFIG,
      plugins: [...MAP_CONFIG.plugins, 'AMap.Geocoder']
    });
    
    return new Promise((resolve, reject) => {
      const geocoder = new AMap.Geocoder({
        city: "", // 不限制城市范围
        radius: 1000 // 搜索半径
      });
      
      geocoder.getLocation(address, function(status, result) {
        if (status === 'complete' && result.info === 'OK' && result.geocodes && result.geocodes.length > 0) {
          // 获取第一个地理编码结果
          const location = result.geocodes[0].location;
          resolve([location.lng, location.lat]);
        } else {
          // 高德地图API地理编码失败，尝试从logistics.js中导入备选方法
          console.warn('高德地图地理编码失败，尝试使用备选坐标方法');
          
          // 这里我们不能直接导入，因为会造成循环依赖
          // 而是根据地址特征返回常用城市坐标
          let backupCoords;
          
          // 简单的地址特征匹配逻辑，与logistics.js中类似
          if (address.includes('福建') || address.includes('莆田')) {
            backupCoords = [119.007558, 25.454208]; // 福建省莆田市坐标
          } else if (address.includes('贵州') || address.includes('黔西南')) {
            backupCoords = [104.891276, 25.088025]; // 贵州省黔西南州坐标
          } else if (address.includes('北京')) {
            backupCoords = [116.483371, 39.941752]; // 北京市朝阳区坐标
          } else if (address.includes('上海')) {
            backupCoords = [121.613939, 31.207767]; // 上海市浦东新区坐标
          } else {
            // 使用默认坐标
            backupCoords = address.includes('收货') ? 
              [116.483371, 39.941752] : // 默认收货地为北京
              [121.613939, 31.207767];  // 默认发货地为上海
          }
          
          console.log('使用备选坐标:', backupCoords, '用于地址:', address);
          resolve(backupCoords);
        }
      });
    });
  } catch (e) {
    console.error('地理编码失败:', e);
    
    // 同样在异常情况下提供备选坐标
    let backupCoords;
    if (address.includes('福建') || address.includes('莆田')) {
      backupCoords = [119.007558, 25.454208];
    } else if (address.includes('贵州') || address.includes('黔西南')) {
      backupCoords = [104.891276, 25.088025];
    } else if (address.includes('北京')) {
      backupCoords = [116.483371, 39.941752];
    } else if (address.includes('上海')) {
      backupCoords = [121.613939, 31.207767];
    } else {
      backupCoords = address.includes('收货') ? 
        [116.483371, 39.941752] : 
        [121.613939, 31.207767];
    }
    
    console.log('地理编码完全失败，使用硬编码备选坐标:', backupCoords);
    return backupCoords;
  }
};

/**
 * 逆地理编码 - 坐标转地址
 * @param {Array} position - 坐标 [lng, lat]
 * @returns {Promise<Object>} - 地址信息
 */
export const regeocode = async (position) => {
  try {
    // 确保position是有效的
    if (!position || (!Array.isArray(position) && (!position.lng && !position.lat))) {
      return { formattedAddress: '未知位置' };
    }

    // 规范化坐标格式
    const lngLat = Array.isArray(position) 
      ? position 
      : [position.lng, position.lat];
    
    // 创建一个超时Promise
    const timeoutPromise = new Promise((_, reject) => {
      setTimeout(() => reject(new Error('逆地理编码请求超时')), 5000);
    });
    
    try {
      const AMap = await AMapLoader.load({
        ...MAP_CONFIG,
        plugins: [...MAP_CONFIG.plugins, 'AMap.Geocoder']
      });
      
      // 使用Promise.race处理可能的超时
      return await Promise.race([
        new Promise((resolve, reject) => {
          try {
            const geocoder = new AMap.Geocoder({
              radius: 1000, // 搜索半径
              extensions: 'base' // 返回基本地址信息即可
            });
            
            geocoder.getAddress(lngLat, function(status, result) {
              if (status === 'complete' && result.info === 'OK') {
                resolve(result.regeocode);
              } else {
                // 即使逆地理编码失败，也返回一个基本对象，避免抛出错误
                resolve({
                  formattedAddress: `坐标点(${lngLat[0].toFixed(3)}, ${lngLat[1].toFixed(3)})`
                });
              }
            });
          } catch (innerError) {
            // 捕获调用过程中可能出现的其他错误
            resolve({
              formattedAddress: `坐标点(${lngLat[0].toFixed(3)}, ${lngLat[1].toFixed(3)})`
            });
          }
        }),
        timeoutPromise
      ]);
    } catch (loadError) {
      // 如果AMap加载失败，返回坐标信息
      return {
        formattedAddress: `坐标点(${lngLat[0].toFixed(3)}, ${lngLat[1].toFixed(3)})`
      };
    }
  } catch (e) {
    console.error('逆地理编码失败:', e);
    // 返回一个基本对象而不是抛出错误
    return {
      formattedAddress: '位置获取失败'
    };
  }
};

export default {
  initAMap,
  createLogisticsRoute,
  planLogisticsRoute,
  geocodeAddress,
  regeocode
}; 